home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Hot Mix 17
/
Hot Mix 17.iso
/
HM17_SGI
/
research
/
lib
/
read_gif.pro
< prev
next >
Wrap
Text File
|
1997-07-08
|
6KB
|
230 lines
; $Id: read_gif.pro,v 1.8 1997/03/12 20:52:36 stevep Exp $
;
; Copyright (c) 1992-1997, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
; GifReadByte
; Read a single byte out of the given file
;
FUNCTION GifReadByte, unit
ch = 0b
READU, unit, ch
RETURN, ch
END
PRO READ_GIF, FILE, IMAGE, R, G, B, MULTIPLE=mult, CLOSE=close
;
;+
; NAME:
; READ_GIF
;
; PURPOSE:
; Read the contents of a GIF format image file and return the image
; and color table vectors (if present) in the form of IDL variables.
;
; CATEGORY:
; Input/Output.
;
; CALLING SEQUENCE:
; READ_GIF, File, Image [, R, G, B]
;
; INPUTS:
; File: Scalar string giving the name of the rasterfile to read
;
; Keyword Inputs:
; CLOSE = if set, closes any open file and returns if the MULTIPLE images
; per file mode was used. This keyword is used
; without additional parameters.
;
; MULTIPLE = if set, read files containing multiple images per
; file. Each call to READ_GIF returns the next image,
; with the file remaining open between calls. The File
; parameter is ignored after the first call. Reading
; past the last image returns a scalar value of -1 in IMAGE, and
; closes the file. When reading the 2nd and subsequent
; images, R, G, and B are not returned.
;
; OUTPUTS:
; Image: The 2D byte array to contain the image.
;
;
; OPTIONAL OUTPUT PARAMETERS:
; R, G, B: The variables to contain the Red, Green, and Blue color vectors
; if the rasterfile containes colormaps.
;
; SIDE EFFECTS:
; None.
;
; COMMON BLOCKS:
; READ_GIF_COMMON.
; RESTRICTIONS:
; This routine only reads in the first image in a file (the format
; allows many). Local colormaps are not supported.
; Only 8 bit images are supported.
;
; The Graphics Interchange Format(c) is the Copyright property
; of CompuServ Incorporated. GIF(sm) is a Service Mark property of
; CompuServ Incorporated.
;
; EXAMPLE:
; To open and read the GIF image file named "foo.gif" in the current
; directory, store the image in the variable IMAGE1, and store the color
; vectors in the variables R, G, and B, enter:
;
; READ_GIF, "foo.gif", IMAGE1, R, G, B
;
; To load the new color table and display the image, enter:
;
; TVLCT, R, G, B
; TV, IMAGE1
;
; MODIFICATION HISTORY:
; Written June 1992, JWG
; Added GIF89a and interlaced format, Jan, 1995, DMS.
; Added MULTIPLE and CLOSE, Aug, 1996.
;
;-
; Copyright (c) 1992-1996, Research Systems, Inc. All rights reserved.
; Unauthorized reproduction prohibited.
;
; Define GIF header (and screen descriptor)
COMMON READ_GIF_COMMON, unit, width, height
if n_elements(unit) eq 0 then unit = -1
on_error, 2 ;Return to caller on errors
image = -1 ;No image read yet
if keyword_set(close) then begin
if unit gt 0 then FREE_LUN, unit
unit = -1
return
endif
h = { magic:bytarr(6), $
width_lo:0b, width_hi:0b, $
height_lo:0b, height_hi:0b, $
screen_info:0b, background:0b, reserved:0b }
; Image header declaration
ihdr = { left:0, top:0, $ ; we read this but
iwidth:0, iheight:0, $ ; mostly we ignore
image_info:0b } ; its content
if keyword_set(mult) and unit gt 0 then goto, next_image
if unit gt 0 then free_lun, unit
OPENR, unit, file, /GET_LUN, /BLOCK, ERROR=i
if i ne 0 then message, 'Error occured opening file: '+file+'.'
READU, unit, h ;Read gif header
; Check Magic in header: GIF87a or GIF89a.
gif = STRING(h.magic[0:2])
vers = STRING(h.magic[3:5])
IF gif NE 'GIF' THEN BEGIN
FREE_LUN, unit
unit = -1
MESSAGE, 'File ' + file + ' is not a GIF file.'
ENDIF
IF vers ne '87a' and vers ne '89a' then $
MESSAGE, /INFO, 'GIF Version incompatible:'+vers+'.'
width = h.width_hi * 256 + h.width_lo
height = h.height_hi * 256 + h.height_lo
; Find out how big the color map is
bits_per_pixel = (h.screen_info AND 'F'X) + 1
color_map_size = 2 ^ bits_per_pixel
; Read in the colormap (optional)
IF (h.screen_info AND '80'X) NE 0 THEN BEGIN
map = BYTARR(3,color_map_size, /NOZERO)
READU, unit, map
map = transpose(map)
r = map[*,0]
g = map[*,1]
b = map[*,2]
ENDIF
; Read the image description
next_image: while 1 do begin ;Read till we get a terminator
cmd = GifReadByte(unit) ;Loop thru commands in file.
CASE STRING(cmd) OF
';': BEGIN ; GIF trailer (0x3b)
FREE_LUN, unit
unit = -1
return
ENDCASE
',': BEGIN ; Image description (0x2c)
READU,unit,ihdr
; Check for file formats we don't support
; We don't support local colormaps
if (ihdr.image_info AND '80'X) NE 0 THEN begin ;Local color map
lcolor_map_size = 2^((ihdr.image_info and 7) + 1)
junk = bytarr(3, lcolor_map_size, /NOZERO)
readu, unit, junk
message,'Local colormaps ignored.', /CONTINUE
endif
; Allocate an array to hold the image
image = BYTARR(width, height, /NOZERO)
; Now call special GIF-LZW routine hidden within IDL
; to do the ugly serial bit stream decoding
DECODE_GIF,unit,image ; magic
; This should be the 0 byte that ends the series:
dummy = GifReadByte(unit) ;Loop thru commands in file.
if dummy ne 0 then message,/info,'No trailing 0.'
; Reorder rows in an interlaced image
if (ihdr.image_info AND '40'X) NE 0 THEN BEGIN
l = lindgen(height) ;Row indices...
;Giff interlace ordering
p = [l[where(l mod 8 eq 0)], l[where(l mod 8 eq 4)], $
l[where(l mod 4 eq 2)], l[where(l and 1)]]
image2 = bytarr(width, height, /NOZERO)
h1 = height-1
for i=0, h1 do image2[0, h1-p[i]] = image[*,h1-i]
image = temporary(image2)
ENDIF
if keyword_set(mult) then return ;Leave file open
FREE_LUN, unit
unit = -1
RETURN
ENDCASE
'!': BEGIN ;Gif Extention block (ignored) (0x21)
label = GifReadByte(unit) ;toss extension block label
repeat begin ;read and ignore blkss
blk_size = GifReadByte(unit) ;block size
if blk_size ne 0 then begin
junk = BYTARR(blk_size, /NOZERO)
READU, unit, junk
endif
endrep until blk_size eq 0
ENDCASE
ELSE: message,'Unknown GIF keyword in ' + file + string(cmd, format='(2x,Z2)')
ENDCASE
endwhile
END